from datetime import datetime
import os
import glob


def calculate_statistics(test_results):
    """根据测试结果计算统计数据"""
    total_tests = len(test_results)
    passed_tests = len([result for result in test_results if result['status'] == 'passed'])
    failed_tests = len([result for result in test_results if result['status'] == 'failed'])
    error_tests = len([result for result in test_results if result['status'] == 'error'])
    skipped_tests = len([result for result in test_results if result['status'] == 'skipped'])

    # 计算成功率
    success_rate = (passed_tests / total_tests * 100) if total_tests > 0 else 0

    # 计算总执行时间（假设每个结果都有以秒为单位的execution_time字段）
    total_duration = 0
    for result in test_results:
        exec_time = result.get('execution_time', '0s')
        # 处理字符串格式的时间，提取数字部分
        if isinstance(exec_time, str):
            # 去除末尾的's'字符并转换为浮点数
            try:
                total_duration += float(exec_time.rstrip('s'))
            except ValueError:
                # 如果转换失败，跳过该值
                pass
        else:
            total_duration += exec_time

    return {
        'success_rate': success_rate,
        'total_cases': total_tests,
        'passed_cases': passed_tests,
        'failed_cases': failed_tests,  # 失败的用例（断言失败等）
        'error_cases': error_tests,    # 错误的用例（异常等）
        'skipped_cases': skipped_tests,
        'duration': f"{total_duration:.2f}s"
    }


def find_screenshot_for_case(case_name, report_dir):
    """查找与测试用例相关的截图文件"""
    screenshot_dir = os.path.join(report_dir, "screenshots")
    if not os.path.exists(screenshot_dir):
        return []
    
    # 查找所有以case_name开头的截图文件
    pattern = os.path.join(screenshot_dir, f"{case_name}_*.png")
    matching_files = glob.glob(pattern)
    
    # 如果没有精确匹配，尝试模糊匹配（查找包含case_name的截图）
    if not matching_files:
        all_screenshots = glob.glob(os.path.join(screenshot_dir, "*.png"))
        matching_files = [s for s in all_screenshots if case_name in os.path.basename(s)]
    
    return matching_files


def _generate_summary_section(f, test_results):
    """生成报告摘要部分"""
    f.write("<h2>测试总结</h2>")

    stats = calculate_statistics(test_results)
    
    # 汇总信息
    f.write(f"<p>总共测试用例数: {stats['total_cases']}</p>")
    f.write(f"<p class='passed'>通过: {stats['passed_cases']}</p>")
    f.write(f"<p class='failed'>失败: {stats['failed_cases']}</p>")
    f.write(f"<p class='error'>错误: {stats['error_cases']}</p>")
    f.write(f"<p>跳过: {stats['skipped_cases']}</p>")
    f.write(f"<p>成功率: {stats['success_rate']:.2f}%</p>")
    f.write(f"<p>总耗时: {stats['duration']}</p>")


def _generate_test_details_section(f, test_results, report_dir):
    """生成测试详情表格部分"""
    f.write("<h2>测试结果详情</h2>")
    f.write("""
    <table>
        <tr>
            <th>测试用例</th>
            <th>状态</th>
            <th>执行时间</th>
            <th>错误详情</th>
            <th>截图</th>
        </tr>
    """)
    
    for result in test_results:
        status_class = result['status']
        f.write("<tr>")
        f.write(f"<td>{result['test_case']}</td>")
        f.write(f"<td class='{status_class}'>{result['status']}</td>")
        f.write(f"<td>{result.get('execution_time', 'N/A')}</td>")
        
        # 错误详情
        error_details = result.get('error_details', '')
        f.write(f"<td><pre>{error_details}</pre></td>")
        
        # 截图链接
        screenshots = result.get('screenshots', [])
        if screenshots:
            screenshot_html = ""
            for screenshot in screenshots:
                if os.path.exists(screenshot):
                    relative_screenshot_path = os.path.relpath(screenshot, report_dir)
                    screenshot_html += f"<div class='screenshot-container'><a href='{relative_screenshot_path}' target='_blank'>查看截图</a></div>"
            if screenshot_html:
                f.write(f"<td>{screenshot_html}</td>")
            else:
                f.write("<td>截图文件不存在</td>")
        else:
            # 尝试查找匹配的截图文件
            case_name = result['test_case']
            found_screenshots = find_screenshot_for_case(case_name, report_dir)
            if found_screenshots:
                screenshot_html = ""
                for screenshot in found_screenshots:
                    if os.path.exists(screenshot):
                        relative_screenshot_path = os.path.relpath(screenshot, report_dir)
                        screenshot_html += f"<div class='screenshot-container'><a href='{relative_screenshot_path}' target='_blank'>查看截图</a></div>"
                f.write(f"<td>{screenshot_html}</td>")
            else:
                f.write("<td>无截图</td>")
        f.write("</tr>")
    f.write("</table>")


def _generate_screenshots_section(f, test_results, report_dir):
    """生成截图展示部分"""
    f.write("<h2>测试截图详情</h2>")
    
    has_screenshots = False
    for result in test_results:
        # 获取截图
        screenshots = result.get('screenshots', [])
        if not screenshots:
            # 尝试查找匹配的截图文件
            screenshots = find_screenshot_for_case(result['test_case'], report_dir)
        
        if screenshots:
            has_screenshots = True
            f.write(f"<h3>测试用例: {result['test_case']} <span class='{result['status']}'>{result['status']}</span></h3>")
            
            # 显示错误详情
            error_details = result.get('error_details', '')
            if error_details:
                f.write(f"<p><strong>错误详情:</strong></p><pre>{error_details}</pre>")
            
            # 显示截图
            for i, screenshot in enumerate(screenshots):
                if os.path.exists(screenshot):
                    relative_screenshot_path = os.path.relpath(screenshot, report_dir)
                    f.write(f"<div class='screenshot-title'>截图 {i+1}:</div>")
                    f.write(f"<img src='{relative_screenshot_path}' alt='测试截图'>")
                else:
                    f.write(f"<p class='missing-screenshot'>截图文件不存在: {screenshot}</p>")
            f.write("<hr>")
    
    if not has_screenshots:
        f.write("<p>未生成任何截图</p>")


def generate_report(test_results):
    """生成HTML格式的测试报告"""
    # 获取项目根目录的绝对路径
    project_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    report_dir = os.path.join(project_root, "reports")
    os.makedirs(report_dir, exist_ok=True)
    report_path = os.path.join(report_dir, "report.html")

    with open(report_path, "w", encoding="utf-8") as f:
        # 写入HTML头部
        f.write("""
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>自动化测试报告</title>
    <style>
        body { 
            font-family: Arial, sans-serif; 
            margin: 20px; 
            background-color: #f5f5f5;
        }
        .container {
            max-width: 1200px;
            margin: 0 auto;
            background-color: white;
            padding: 20px;
            border-radius: 8px;
            box-shadow: 0 2px 10px rgba(0,0,0,0.1);
        }
        h1, h2, h3 {
            color: #333;
        }
        table { 
            width: 100%; 
            border-collapse: collapse; 
            margin: 20px 0; 
            box-shadow: 0 1px 3px rgba(0,0,0,0.1);
        }
        table, th, td { 
            border: 1px solid #ddd; 
            padding: 12px; 
            text-align: left;
        }
        th { 
            background-color: #f2f2f2; 
            font-weight: bold;
        }
        tr:nth-child(even) { 
            background-color: #f9f9f9; 
        }
        tr:hover {
            background-color: #f0f8ff;
        }
        img { 
            width: 600px; 
            height: auto; 
            max-width: 100%; 
            border: 1px solid #ddd;
            border-radius: 4px;
            box-shadow: 0 1px 3px rgba(0,0,0,0.1);
        }
        .missing-screenshot { 
            color: #888; 
            font-style: italic; 
        }
        .error { 
            color: #d9534f; 
            font-weight: bold;
        }
        .failed { 
            color: #f0ad4e; 
            font-weight: bold;
        }
        .passed { 
            color: #5cb85c; 
            font-weight: bold;
        }
        .screenshot-container { 
            margin: 10px 0; 
        }
        .screenshot-title { 
            font-weight: bold; 
            margin: 15px 0 5px 0; 
            color: #555;
        }
        pre {
            background-color: #f8f9fa;
            border: 1px solid #e9ecef;
            border-radius: 4px;
            padding: 12px;
            overflow-x: auto;
            max-height: 300px;
        }
        hr {
            margin: 30px 0;
            border: 0;
            border-top: 1px solid #eee;
        }
        .summary-stats {
            display: flex;
            flex-wrap: wrap;
            gap: 20px;
            margin: 20px 0;
        }
        .stat-card {
            background-color: #f8f9fa;
            border-radius: 8px;
            padding: 15px;
            min-width: 150px;
            text-align: center;
            box-shadow: 0 1px 3px rgba(0,0,0,0.1);
        }
        .stat-card.passed {
            border-left: 4px solid #5cb85c;
        }
        .stat-card.failed {
            border-left: 4px solid #f0ad4e;
        }
        .stat-card.error {
            border-left: 4px solid #d9534f;
        }
    </style>
</head>
<body>
<div class="container">
        """)

        # 报告标题和生成时间
        f.write("<h1>自动化测试报告</h1>")
        f.write(f"<p>报告生成时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}</p>")
        
        # 摘要部分
        _generate_summary_section(f, test_results)
        
        # 测试详情表格
        _generate_test_details_section(f, test_results, report_dir)
        
        # 截图展示部分
        _generate_screenshots_section(f, test_results, report_dir)

        # 结束标签
        f.write("""
</div>
</body>
</html>
        """)

    return report_path